<?php
// +----------------------------------------------------------------------
// | OneThink [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013 http://www.onethink.cn All rights reserved.
// +----------------------------------------------------------------------
// | Author: yangweijie <yangweijiester@gmail.com> <code-tech.diandian.com>
// +----------------------------------------------------------------------

namespace Admin\Controller;

/**
 * 扩展后台管理页面
 * @author yangweijie <yangweijiester@gmail.com>
 */
class AddonsController extends AdminController {

	public function _initialize() {
		$this->assign('_extra_menu', array(
			'已装插件后台' => D('Addons')->getAdminList(),
		));
		parent::_initialize();
	}

	//创建向导首页
	public function create() {
		if (!is_writable(ONETHINK_ADDON_PATH)) {
			$this->error('您没有创建目录写入权限，无法使用此功能');
		}

		$hooks = M('Hooks')->field('name,description')->select();
		$this->assign('Hooks', $hooks);
		$this->meta_title = '创建向导';
		$this->display('create');
	}

	//预览
	public function preview($output = true) {
		$data = $_POST;
		$data['info']['status'] = (int) $data['info']['status'];
		$extend = array();
		$custom_config = trim($data['custom_config']);
		if ($data['has_config'] && $custom_config) {
			$custom_config = <<<str

    public \$custom_config = '{$custom_config}';
str;
			$extend[] = $custom_config;
		}

		$admin_list = trim($data['admin_list']);
		if ($data['has_adminlist'] && $admin_list) {
			$admin_list = <<<str

    public \$admin_list = array(
        {$admin_list}
    );
str;
			$extend[] = $admin_list;
		}

		$custom_adminlist = trim($data['custom_adminlist']);
		if ($data['has_adminlist'] && $custom_adminlist) {
			$custom_adminlist = <<<str

    public \$custom_adminlist = '{$custom_adminlist}';
str;
			$extend[] = $custom_adminlist;
		}

		$extend = implode('', $extend);
		$hook = '';
		foreach ($data['hook'] as $value) {
			$hook .= <<<str
    //实现的{$value}钩子方法
    public function {$value}(\$param){

    }

str;
		}

		$tpl = <<<str
<?php
namespace Addons\\{$data['info']['name']};
use Common\Controller\Addon;

/**
 * {$data['info']['title']}插件
 * @author {$data['info']['author']}
 */
class {$data['info']['name']}Addon extends Addon{

    public \$info = array(
        'name'=>'{$data['info']['name']}',
        'title'=>'{$data['info']['title']}',
        'description'=>'{$data['info']['description']}',
        'status'=>{$data['info']['status']},
        'author'=>'{$data['info']['author']}',
        'version'=>'{$data['info']['version']}'
    );
	{$extend}

    public function install(){
        return true;
    }

    public function uninstall(){
        return true;
    }

{$hook}
}
str;
		if ($output) {
			exit($tpl);
		} else {
			return $tpl;
		}

	}

	public function checkForm() {
		$data = $_POST;
		$data['info']['name'] = trim($data['info']['name']);
		if (!$data['info']['name']) {
			$this->error('插件标识必须');
		}

		//检测插件名是否合法
		$addons_dir = ONETHINK_ADDON_PATH;
		if (file_exists("{$addons_dir}{$data['info']['name']}")) {
			$this->error('插件已经存在了');
		}
		$this->success('可以创建');
	}

	public function build() {
		$data = $_POST;
		$data['info']['name'] = trim($data['info']['name']);
		$addonFile = $this->preview(false);
		$addons_dir = ONETHINK_ADDON_PATH;
		//创建目录结构
		$files = array();
		$addon_dir = "$addons_dir{$data['info']['name']}/";
		$files[] = $addon_dir;
		$addon_name = "{$data['info']['name']}Addon.class.php";
		$files[] = "{$addon_dir}{$addon_name}";
		if ($data['has_config'] == 1); //如果有配置文件
		$files[] = $addon_dir . 'config.php';

		if ($data['has_outurl']) {
			$files[] = "{$addon_dir}Controller/";
			$files[] = "{$addon_dir}Controller/{$data['info']['name']}Controller.class.php";
			$files[] = "{$addon_dir}Model/";
			$files[] = "{$addon_dir}Model/{$data['info']['name']}Model.class.php";
		}
		$custom_config = trim($data['custom_config']);
		if ($custom_config) {
			$data[] = "{$addon_dir}{$custom_config}";
		}

		$custom_adminlist = trim($data['custom_adminlist']);
		if ($custom_adminlist) {
			$data[] = "{$addon_dir}{$custom_adminlist}";
		}

		create_dir_or_files($files);

		//写文件
		file_put_contents("{$addon_dir}{$addon_name}", $addonFile);
		if ($data['has_outurl']) {
			$addonController = <<<str
<?php
namespace Addons\\{$data['info']['name']}\Controller;
use Home\Controller\AddonsController;

class {$data['info']['name']}Controller extends AddonsController{

}

str;
			file_put_contents("{$addon_dir}Controller/{$data['info']['name']}Controller.class.php", $addonController);
			$addonModel = <<<str
<?php
namespace Addons\\{$data['info']['name']}\Model;
use Think\Model;

/**
 * {$data['info']['name']}模型
 */
class {$data['info']['name']}Model extends Model{
    public \$model = array(
        'title'=>'',//新增[title]、编辑[title]、删除[title]的提示
        'template_add'=>'',//自定义新增模板自定义html edit.html 会读取插件根目录的模板
        'template_edit'=>'',//自定义编辑模板html
        'search_key'=>'',// 搜索的字段名，默认是title
        'extend'=>1,
    );

    public \$_fields = array(
        'id'=>array(
            'name'=>'id',//字段名
            'title'=>'ID',//显示标题
            'type'=>'num',//字段类型
            'remark'=>'',// 备注，相当于配置里的tip
            'is_show'=>3,// 1-始终显示 2-新增显示 3-编辑显示 0-不显示
            'value'=>0,//默认值
        ),
        'title'=>array(
            'name'=>'title',
            'title'=>'书名',
            'type'=>'string',
            'remark'=>'',
            'is_show'=>1,
            'value'=>0,
            'is_must'=>1,
        ),
    );
}

str;
			file_put_contents("{$addon_dir}Model/{$data['info']['name']}Model.class.php", $addonModel);
		}

		if ($data['has_config'] == 1) {
			file_put_contents("{$addon_dir}config.php", $data['config']);
		}

		$this->success('创建成功', U('index'));
	}

	/**
	 * 插件列表
	 */
	public function index() {
		$this->meta_title = '插件列表';
		$list = D('Addons')->getList();
		$request = (array) I('request.');
		$total = $list ? count($list) : 1;
		$listRows = C('LIST_ROWS') > 0 ? C('LIST_ROWS') : 20;
		$page = new \Think\Page($total, $listRows);
		$voList = array_slice($list, $page->firstRow, $page->listRows);
		$p = $page->show();
		$this->assign('_list', $voList);
		$this->assign('_page', $p ? $p : '');
		// 记录当前列表页的cookie
		Cookie('__forward__', $_SERVER['REQUEST_URI']);
		$this->display();
	}

	/**
	 * 插件后台显示页面
	 * @param string $name 插件名
	 */
	public function adminList($name) {

		if (method_exists(A('Addons://' . $name . '/Admin'), 'buildList')) {
			A('Addons://' . $name . '/Admin')->buildList();
			exit;
		}

		// 记录当前列表页的cookie
		Cookie('__forward__', $_SERVER['REQUEST_URI']);
		$class = get_addon_class($name);
		if (!class_exists($class)) {
			$this->error('插件不存在');
		}

		$addon = new $class();
		$this->assign('addon', $addon);
		$param = $addon->admin_list;
		if (!$param) {
			$this->error('插件列表信息不正确');
		}

		$this->meta_title = $addon->info['title'];
		extract($param);
		$this->assign('title', $addon->info['title']);
		$this->assign($param);
		if (!isset($fields)) {
			$fields = '*';
		}

		if (!isset($map)) {
			$map = array();
		}

		if (isset($model)) {
			$list = $this->lists(D("Addons://{$model}/{$model}")->field($fields), $map, $order);
		}

		$this->assign('_list', $list);
		if ($addon->custom_adminlist) {
			$this->assign('custom_adminlist', $this->fetch($addon->addon_path . $addon->custom_adminlist));
		}

		$this->display();
	}

	/**
	 * 启用插件
	 */
	public function enable() {
		$id = I('id', 0, 'intval');
		$msg = array('success' => '启用成功', 'error' => '启用失败');
		S('hooks', null);
		$this->resume('Addons', "id={$id}", $msg);
	}

	/**
	 * 禁用插件
	 */
	public function disable() {
		$id = I('id', 0, 'intval');
		$msg = array('success' => '禁用成功', 'error' => '禁用失败');
		S('hooks', null);
		$this->forbid('Addons', "id={$id}", $msg);
	}

	/**
	 * 设置插件页面
	 */
	public function config() {
		$id = I('id', 0, 'intval');
		$addon = M('Addons')->find($id);
		if (!$addon) {
			$this->error('插件未安装');
		}

		$addon_class = get_addon_class($addon['name']);
		if (!class_exists($addon_class)) {
			trace("插件{$addon['name']}无法实例化,", 'ADDONS', 'ERR');
		}

		$data = new $addon_class;
		$addon['addon_path'] = $data->addon_path;
		$addon['custom_config'] = $data->custom_config;
		$this->meta_title = '设置插件-' . $data->info['title'];
		$db_config = $addon['config'];
		$addon['config'] = include $data->config_file;
		if ($db_config) {
			$db_config = json_decode($db_config, true);
			foreach ($addon['config'] as $key => $value) {
				if ($value['type'] != 'group') {
					$addon['config'][$key]['value'] = $db_config[$key];
				} else {
					foreach ($value['options'] as $gourp => $options) {
						foreach ($options['options'] as $gkey => $value) {
							$addon['config'][$key]['options'][$gourp]['options'][$gkey]['value'] = $db_config[$gkey];
						}
					}
				}
			}
		}
		$this->assign('data', $addon);
		if ($addon['custom_config']) {
			$this->assign('custom_config', $this->fetch($addon['addon_path'] . $addon['custom_config']));
		}

		$this->display();
	}

	/**
	 * 保存插件设置
	 */
	public function saveConfig() {
		$id = I('id', 0, 'intval');
		$config = I('config');
		$flag = M('Addons')->where("id={$id}")->setField('config', json_encode($config));
		if (isset($config['addons_cache'])) {
			//清除缓存
			S($config['addons_cache'], null);
		}
		if ($flag !== false) {
			$this->success('保存成功', Cookie('__forward__'));
		} else {
			$this->error('保存失败');
		}
	}

	/**
	 * 安装插件
	 */
	public function install() {
		$addon_name = trim(I('addon_name'));
		$class = get_addon_class($addon_name);
		if (!class_exists($class)) {
			$this->error('插件不存在');
		}

		$addons = new $class;
		$info = $addons->info;
		if (!$info || !$addons->checkInfo()) {
			//检测信息的正确性
			$this->error('插件信息缺失');
		}

		session('addons_install_error', null);
		$install_flag = $addons->install();
		if (!$install_flag) {
			$this->error('执行插件预安装操作失败' . session('addons_install_error'));
		}

		// =====================================
		// 添加钩子到数据库
		// @author Wenhui Shen <swh@admpub.com>
		// =====================================
		$hooks = D('Hooks');
		if (!empty($addons->info['hooks'])) {
			foreach ($addons->info['hooks'] as $key => $value) {
				if ($hook = $hooks->where(array('name' => $key))->find()) {
					$addons = $hook['addons'] ? explode(',', $hook['addons']) : array();
					if ($value['addons']) {
						$newAddons = explode(',', $value['addons']);
						$newAddons = array_diff($newAddons, $addons);
						if ($newAddons) {
							foreach ($newAddons as $v) {
								$addons[] = $v;
							}
						}
					}
					$hooks->where(array('id' => $hook['id']))->save(array(
						'update_time' => NOW_TIME,
						'addons' => implode(',', $addons),
					));
				} else {
					$hooks->add(array(
						'name' => $key,
						'description' => $value['description'],
						'type' => $value['type'],
						'update_time' => NOW_TIME,
						'addons' => $value['addons'],
					));
				}
			}
		}

		$addonsModel = D('Addons');
		$data = $addonsModel->create($info);

		if ((is_array($addons->admin_list) && $addons->admin_list !== array()) || method_exists(A('Addons://Mail/Admin'), 'buildList')) {
			$data['has_adminlist'] = 1;
		} else {
			$data['has_adminlist'] = 0;
		}
		if (!$data) {
			$this->error($addonsModel->getError());
		}

		if ($addonsModel->add($data)) {
			$config = array('config' => json_encode($addons->getConfig()));
			$addonsModel->where(array('name' => $addon_name))->save($config);
			$hooks_update = D('Hooks')->updateHooks($addon_name);
			if ($hooks_update) {
				S('hooks', null);
				$this->success('安装成功');
			} else {
				$addonsModel->where(array('name' => $addon_name))->delete();
				$this->error('更新钩子处插件失败,请卸载后尝试重新安装');
			}

		} else {
			$this->error('写入插件数据失败');
		}
	}

	/**
	 * 卸载插件
	 */
	public function uninstall() {
		$addonsModel = M('Addons');
		$id = I('id', 0, 'intval');
		$db_addons = $addonsModel->find($id);
		$class = get_addon_class($db_addons['name']);
		$this->assign('jumpUrl', U('index'));
		if (!$db_addons || !class_exists($class)) {
			$this->error('插件不存在');
		}

		session('addons_uninstall_error', null);
		$addons = new $class;
		$uninstall_flag = $addons->uninstall();
		if (!$uninstall_flag) {
			$this->error('执行插件预卸载操作失败' . session('addons_uninstall_error'));
		}

		$hooks_update = D('Hooks')->removeHooks($db_addons['name']);
		if ($hooks_update === false) {
			$this->error('卸载插件所挂载的钩子数据失败');
		}

		$info = $addons->info;
		// =====================================
		// 删除钩子
		// @author Wenhui Shen <swh@admpub.com>
		// =====================================
		$hooks = D('Hooks');
		if (!empty($addons->info['hooks'])) {
			foreach ($addons->info['hooks'] as $key => $value) {
				if ($hook = $hooks->where(array('name' => $key))->find()) {
					if ($hook['addons'] == $key || $hook['addons'] == '') {
						$hooks->where(array('id' => $hook['id']))->delete();
					} else {
						$addons = explode(',', $hook['addons']);
						if ($value['addons']) {
							$newAddons = explode(',', $value['addons']);
							foreach ($addons as $k => $v) {
								if (in_array($v, $newAddons)) {
									unset($addons[$k]);
								}
							}
						}
						$hooks->where(array('id' => $hook['id']))->setField('addons', implode(',', $addons));
					}
				}
			}
		}

		S('hooks', null);
		$delete = $addonsModel->where(array('name' => $db_addons['name']))->delete();
		if ($delete === false) {
			$this->error('卸载插件失败');
		} else {
			$this->success('卸载成功');
		}
	}

	/**
	 * 钩子列表
	 */
	public function hooks() {
		$this->meta_title = '钩子列表';
		$map = $fields = array();
		$list = $this->lists(D('Hooks')->field($fields), $map);
		int_to_string($list, array('type' => C('HOOKS_TYPE')));
		// 记录当前列表页的cookie
		Cookie('__forward__', $_SERVER['REQUEST_URI']);
		$this->assign('list', $list);
		$this->display();
	}

	public function addhook() {
		$this->assign('data', null);
		$this->meta_title = '新增钩子';
		$this->display('edithook');
	}

	//钩子出编辑挂载插件页面
	public function edithook($id) {
		$hook = M('Hooks')->field(true)->find($id);
		$this->assign('data', $hook);
		$this->meta_title = '编辑钩子';
		$this->display('edithook');
	}

	//超级管理员删除钩子
	public function delhook($id) {
		if (M('Hooks')->delete($id) !== false) {
			S('hooks', null);
			$this->success('删除成功');
		} else {
			$this->error('删除失败');
		}
	}

	public function updateHook() {
		$hookModel = D('Hooks');
		$data = $hookModel->create();
		if ($data) {
			if ($data['id']) {
				$flag = $hookModel->save($data);
				if ($flag !== false) {
					S('hooks', null);
					$this->success('更新成功', Cookie('__SELF__'));
				} else {
					$this->error('更新失败');
				}

			} else {
				$flag = $hookModel->add($data);
				if ($flag) {
					S('hooks', null);
					$this->success('新增成功', Cookie('__forward__'));
				} else {
					$this->error('新增失败');
				}

			}
		} else {
			$this->error($hookModel->getError());
		}
	}

	public function execute($_addons = null, $_controller = null, $_action = null) {
		if (C('URL_CASE_INSENSITIVE')) {
			$_addons = ucfirst(parse_name($_addons, 1));
			$_controller = parse_name($_controller, 1);
		}

		$TMPL_PARSE_STRING = C('TMPL_PARSE_STRING');
		$TMPL_PARSE_STRING['__ADDONROOT__'] = __ROOT__ . "/Addons/{$_addons}";
		C('TMPL_PARSE_STRING', $TMPL_PARSE_STRING);

		if (!empty($_addons) && !empty($_controller) && !empty($_action)) {

			$Addons = A("Addons://{$_addons}/{$_controller}")->$_action();
		} else {
			$this->error('没有指定插件名称，控制器或操作！');
		}
	}

	public function edit($name, $id = 0) {
		$this->assign('name', $name);
		$class = get_addon_class($name);
		if (!class_exists($class)) {
			$this->error('插件不存在');
		}

		$addon = new $class();
		$this->assign('addon', $addon);
		$param = $addon->admin_list;
		if (!$param) {
			$this->error('插件列表信息不正确');
		}

		extract($param);
		$this->assign('title', $addon->info['title']);
		if (isset($model)) {
			$addonModel = D("Addons://{$name}/{$model}");
			if (!$addonModel) {
				$this->error('模型无法实列化');
			}

			$model = $addonModel->model;
			$this->assign('model', $model);
		}
		if ($id) {
			$data = $addonModel->find($id);
			$data || $this->error('数据不存在！');
			$this->assign('data', $data);
		}

		if (IS_POST) {
			// 获取模型的字段信息
			if (!$addonModel->create()) {
				$this->error($addonModel->getError());
			}

			if ($id) {
				$flag = $addonModel->save();
				if ($flag !== false) {
					$this->success("编辑{$model['title']}成功！", Cookie('__forward__'));
				} else {
					$this->error($addonModel->getError());
				}

			} else {
				$flag = $addonModel->add();
				if ($flag) {
					$this->success("添加{$model['title']}成功！", Cookie('__forward__'));
				}

			}
			$this->error($addonModel->getError());
		} else {
			$fields = $addonModel->_fields;
			$this->assign('fields', $fields);
			$this->meta_title = $id ? '编辑' . $model['title'] : '新增' . $model['title'];
			if ($id) {
				$template = $model['template_edit'] ? $model['template_edit'] : '';
			} else {
				$template = $model['template_add'] ? $model['template_add'] : '';
			}

			$this->display($addon->addon_path . $template);
		}
	}

	public function del($id = '', $name) {
		$ids = I('ids', 0, 'toInt');

		if (empty($ids)) {
			$this->error('请选择要操作的数据!');
		}

		$class = get_addon_class($name);
		if (!class_exists($class)) {
			$this->error('插件不存在');
		}

		$addon = new $class();
		$param = $addon->admin_list;
		if (!$param) {
			$this->error('插件列表信息不正确');
		}

		extract($param);
		if (isset($model)) {
			$addonModel = D("Addons://{$name}/{$model}");
			if (!$addonModel) {
				$this->error('模型无法实列化');
			}

		}

		$map = array('id' => array('in', $ids));
		if ($addonModel->where($map)->delete()) {
			$this->success('删除成功');
		} else {
			$this->error('删除失败！');
		}
	}

}
